/**
 * @file analog_data.c
 * @brief 遥测数据模块实现
 * @details 本文件实现了104协议的遥测数据处理功能，包括归一化值、标度化值、
 *          短浮点数、带时标的测量值、累计量等数据类型的序列化和反序列化操作。
 *          支持完整的数据转换和验证功能。
 * 
 * @author zyb
 * @date 2025-10-10
 * @version 1.0
 * 
 * @note 所有函数都遵循104协议规范，确保严格的数据处理
 * @warning 数据转换失败时应返回相应的错误码，便于上层处理
 * 
 * @see analog_data.h
 * @see protocol_types.h
 * @see buffer_utils.h
 * @see time_utils.h
 */

#include "../include/analog_data.h"
#include "../../common/types/include/protocol_types.h"
#include "../../../../../common/utils/include/buffer_utils.h"
#include "../../common/utils/include/time_utils.h"
#include "../../common/error/include/error_codes.h"
#include "../../common/utils/include/validation_utils.h"
#include "../../../../../common/logs/include/logger.h"
#include <string.h>

// 定义模块名称
#define LOG_MODULE_NAME "ANALOG_DATA"

/* ==================== 归一化值处理函数实现 ==================== */

/**
 * @brief 归一化值转换为字节数组
 * @details 将归一化值结构转换为104协议规定的字节数组格式。
 *          按照协议规范进行数据序列化。
 * 
 * @param value 归一化值结构，不能为NULL
 * @param buffer 输出缓冲区，不能为NULL
 * @param buffer_size 缓冲区大小
 * @param actual_length 实际写入长度输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 缓冲区太小
 *         - PROTOCOL_ERROR_INVALID_ADDRESS: 地址无效
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 按照104协议规范进行数据序列化
 * @warning 缓冲区大小必须足够容纳转换后的数据
 * 
 * @see bytes_to_normalized_value
 * @see validate_normalized_value
 * @see buffer_write_u24
 * @see buffer_write_s16
 * @see buffer_write_u8
 */
protocol_error_t normalized_value_to_bytes(const normalized_value_t* value,
                                          u8* buffer, u32 buffer_size, u32* actual_length) {
    LOG_DEBUG(LOG_MODULE_NAME, "转换归一化值到字节数组: value=%p, buffer=%p, buffer_size=%u", 
              value, buffer, buffer_size);
    
    if (value == NULL || buffer == NULL || actual_length == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 验证归一化值 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证归一化值数据: 地址=0x%06X, 值=%d, QDS=0x%02X", 
              value->addr, value->value, *(u8*)&value->qds);
    
    if (!is_info_address_valid(value->addr)) {
        LOG_ERROR(LOG_MODULE_NAME, "信息对象地址无效: 0x%06X", value->addr);
        return PROTOCOL_ERROR_ASDU_INVALID_ADDRESS;
    }
    
    if (!is_normalized_value_valid(value->value)) {
        LOG_ERROR(LOG_MODULE_NAME, "归一化值无效: %d", value->value);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    if (!is_qds_valid(*(uint8_t*)&value->qds)) {
        LOG_ERROR(LOG_MODULE_NAME, "品质描述词无效: 0x%02X", *(u8*)&value->qds);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    LOG_DEBUG(LOG_MODULE_NAME, "归一化值数据验证通过");
    
    /* 检查缓冲区大小 */
    if (buffer_size < 6) { /* 地址(3字节) + 值(2字节) + QDS(1字节) */
        LOG_ERROR(LOG_MODULE_NAME, "缓冲区太小: %u < 6", buffer_size);
        return PROTOCOL_ERROR_BUFFER_TOO_SMALL;
    }
    LOG_DEBUG(LOG_MODULE_NAME, "缓冲区大小检查通过: %u >= 6", buffer_size);
    
    /* 写入信息对象地址 */
    LOG_DEBUG(LOG_MODULE_NAME, "写入信息对象地址: 0x%06X 到缓冲区[0-2]", value->addr);
    buffer_write_u32(buffer, 0, value->addr, 0);
    
    /* 写入归一化值 */
    LOG_DEBUG(LOG_MODULE_NAME, "写入归一化值: %d 到缓冲区[3-4]", value->value);
    buffer_write_u16(&buffer[3], 0, (u16)value->value, 0);
    
    /* 写入品质描述词 */
    LOG_DEBUG(LOG_MODULE_NAME, "写入品质描述词: 0x%02X 到缓冲区[5]", *(u8*)&value->qds);
    buffer[5] = *(u8*)&value->qds;
    
    *actual_length = 6;
    LOG_INFO(LOG_MODULE_NAME, "归一化值成功转换为字节数组，实际长度: %u", *actual_length);
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 字节数组转换为归一化值
 * @details 将104协议规定的字节数组格式转换为归一化值结构。
 *          按照协议规范进行数据反序列化。
 * 
 * @param data 字节数组，不能为NULL
 * @param length 数据长度
 * @param value 归一化值结构输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 数据长度不足
 *         - PROTOCOL_ERROR_INVALID_ADDRESS: 地址无效
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 按照104协议规范进行数据反序列化
 * @warning 数据长度必须足够容纳归一化值
 * 
 * @see normalized_value_to_bytes
 * @see validate_normalized_value
 * @see buffer_read_u24
 * @see buffer_read_s16
 * @see buffer_read_u8
 */
protocol_error_t bytes_to_normalized_value(const u8* data, u32 length,
                                          normalized_value_t* value) {
    LOG_DEBUG(LOG_MODULE_NAME, "从字节数组转换归一化值: data=%p, length=%u, value=%p", 
              data, length, value);
    
    if (data == NULL || value == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 检查数据长度 */
    if (length < 6) { /* 地址(3字节) + 值(2字节) + QDS(1字节) */
        LOG_ERROR(LOG_MODULE_NAME, "数据长度太小: %u < 6", length);
        return PROTOCOL_ERROR_BUFFER_TOO_SMALL;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "数据长度检查通过: %u >= 6", length);
    
    /* 读取信息对象地址 */
    LOG_DEBUG(LOG_MODULE_NAME, "读取信息对象地址从缓冲区[0-2]");
    buffer_read_u32(data, 0, (u32*)&value->addr, 0);
    
    /* 读取归一化值 */
    LOG_DEBUG(LOG_MODULE_NAME, "读取归一化值从缓冲区[3-4]");
    buffer_read_u16(&data[3], 0, (u16*)&value->value, 0);
    
    /* 读取品质描述词 */
    LOG_DEBUG(LOG_MODULE_NAME, "读取品质描述词从缓冲区[5]");
    value->qds = *(qds_t*)&data[5];
    
    LOG_DEBUG(LOG_MODULE_NAME, "读取完成: 地址=0x%06X, 值=%d, QDS=0x%02X", 
              value->addr, value->value, *(u8*)&value->qds);
    
    /* 验证转换后的数据 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证转换后的数据");
    if (!is_info_address_valid(value->addr)) {
        LOG_ERROR(LOG_MODULE_NAME, "信息对象地址无效: 0x%06X", value->addr);
        return PROTOCOL_ERROR_ASDU_INVALID_ADDRESS;
    }
    
    if (!is_normalized_value_valid(value->value)) {
        LOG_ERROR(LOG_MODULE_NAME, "归一化值无效: %d", value->value);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    if (!is_qds_valid(*(uint8_t*)&value->qds)) {
        LOG_ERROR(LOG_MODULE_NAME, "品质描述词无效: 0x%02X", *(u8*)&value->qds);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    LOG_INFO(LOG_MODULE_NAME, "归一化值转换成功: 地址=0x%06X, 值=%d, QDS=0x%02X", 
             value->addr, value->value, *(u8*)&value->qds);
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 验证归一化值
 * @details 验证归一化值结构的完整性和有效性。
 *          检查地址、数值和品质描述词的有效性。
 * 
 * @param value 归一化值结构，不能为NULL
 * @return 验证结果
 *         - 1: 归一化值有效
 *         - 0: 归一化值无效
 * 
 * @note 验证地址、数值和品质描述词的有效性
 * @warning 输入指针不能为NULL
 * 
 * @see is_info_address_valid
 * @see is_normalized_value_valid
 * @see is_qds_valid
 * @see normalized_value_t
 */
int validate_normalized_value(const normalized_value_t* value) {
    if (value == NULL) {
        return 0;
    }
    
    return (is_info_address_valid(value->addr) && 
            is_normalized_value_valid(value->value) && 
            is_qds_valid(*(uint8_t*)&value->qds));
}

/* ==================== 标度化值处理函数实现 ==================== */

/**
 * @brief 标度化值转换为字节数组
 * @details 将标度化值结构转换为104协议规定的字节数组格式。
 *          按照协议规范进行数据序列化。
 * 
 * @param value 标度化值结构，不能为NULL
 * @param buffer 输出缓冲区，不能为NULL
 * @param buffer_size 缓冲区大小
 * @param actual_length 实际写入长度输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 缓冲区太小
 *         - PROTOCOL_ERROR_INVALID_ADDRESS: 地址无效
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 按照104协议规范进行数据序列化
 * @warning 缓冲区大小必须足够容纳转换后的数据
 * 
 * @see bytes_to_scaled_value
 * @see validate_scaled_value
 * @see buffer_write_u24
 * @see buffer_write_s16
 * @see buffer_write_u8
 */
protocol_error_t scaled_value_to_bytes(const scaled_value_t* value,
                                      u8* buffer, u32 buffer_size, u32* actual_length) {
    LOG_DEBUG(LOG_MODULE_NAME, "转换标度化值到字节数组: value=%p, buffer=%p, buffer_size=%u", 
              value, buffer, buffer_size);
    
    if (value == NULL || buffer == NULL || actual_length == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 验证标度化值 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证标度化值数据: 地址=0x%06X, 值=%d, QDS=0x%02X", 
              value->addr, value->value, *(u8*)&value->qds);
    
    if (!is_info_address_valid(value->addr)) {
        LOG_ERROR(LOG_MODULE_NAME, "信息对象地址无效: 0x%06X", value->addr);
        return PROTOCOL_ERROR_ASDU_INVALID_ADDRESS;
    }
    
    if (!is_scaled_value_valid(value->value)) {
        LOG_ERROR(LOG_MODULE_NAME, "标度化值无效: %d", value->value);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    if (!is_qds_valid(*(uint8_t*)&value->qds)) {
        LOG_ERROR(LOG_MODULE_NAME, "品质描述词无效: 0x%02X", *(u8*)&value->qds);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "标度化值数据验证通过");
    
    /* 检查缓冲区大小 */
    if (buffer_size < 6) { /* 地址(3字节) + 值(2字节) + QDS(1字节) */
        LOG_ERROR(LOG_MODULE_NAME, "缓冲区太小: %u < 6", buffer_size);
        return PROTOCOL_ERROR_BUFFER_TOO_SMALL;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "缓冲区大小检查通过: %u >= 6", buffer_size);
    
    /* 写入信息对象地址 */
    LOG_DEBUG(LOG_MODULE_NAME, "写入信息对象地址: 0x%06X 到缓冲区[0-2]", value->addr);
    buffer_write_u32(buffer, 0, value->addr, 0);
    
    /* 写入标度化值 */
    LOG_DEBUG(LOG_MODULE_NAME, "写入标度化值: %d 到缓冲区[3-4]", value->value);
    buffer_write_u16(&buffer[3], 0, (u16)value->value, 0);
    
    /* 写入品质描述词 */
    LOG_DEBUG(LOG_MODULE_NAME, "写入品质描述词: 0x%02X 到缓冲区[5]", *(u8*)&value->qds);
    buffer[5] = *(u8*)&value->qds;
    
    *actual_length = 6;
    LOG_INFO(LOG_MODULE_NAME, "标度化值转换成功: 地址=0x%06X, 值=%d, QDS=0x%02X, 长度=%u", 
             value->addr, value->value, *(u8*)&value->qds, *actual_length);
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 字节数组转换为标度化值
 * @details 将104协议规定的字节数组格式转换为标度化值结构。
 *          按照协议规范进行数据反序列化。
 * 
 * @param data 字节数组，不能为NULL
 * @param length 数据长度
 * @param value 标度化值结构输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 数据长度不足
 *         - PROTOCOL_ERROR_INVALID_ADDRESS: 地址无效
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 按照104协议规范进行数据反序列化
 * @warning 数据长度必须足够容纳标度化值
 * 
 * @see scaled_value_to_bytes
 * @see validate_scaled_value
 * @see buffer_read_u24
 * @see buffer_read_s16
 * @see buffer_read_u8
 */
protocol_error_t bytes_to_scaled_value(const u8* data, u32 length,
                                      scaled_value_t* value) {
    LOG_DEBUG(LOG_MODULE_NAME, "从字节数组转换标度化值: data=%p, length=%u, value=%p", 
              data, length, value);
    
    if (data == NULL || value == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 检查数据长度 */
    if (length < 6) { /* 地址(3字节) + 值(2字节) + QDS(1字节) */
        LOG_ERROR(LOG_MODULE_NAME, "数据长度太小: %u < 6", length);
        return PROTOCOL_ERROR_BUFFER_TOO_SMALL;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "数据长度检查通过: %u >= 6", length);
    
    /* 读取信息对象地址 */
    LOG_DEBUG(LOG_MODULE_NAME, "读取信息对象地址从缓冲区[0-2]");
    buffer_read_u32(data, 0, (u32*)&value->addr, 0);
    
    /* 读取标度化值 */
    LOG_DEBUG(LOG_MODULE_NAME, "读取标度化值从缓冲区[3-4]");
    buffer_read_u16(&data[3], 0, (u16*)&value->value, 0);
    
    /* 读取品质描述词 */
    LOG_DEBUG(LOG_MODULE_NAME, "读取品质描述词从缓冲区[5]");
    value->qds = *(qds_t*)&data[5];
    
    LOG_DEBUG(LOG_MODULE_NAME, "读取完成: 地址=0x%06X, 值=%d, QDS=0x%02X", 
              value->addr, value->value, *(u8*)&value->qds);
    
    /* 验证转换后的数据 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证转换后的数据");
    if (!is_info_address_valid(value->addr)) {
        LOG_ERROR(LOG_MODULE_NAME, "信息对象地址无效: 0x%06X", value->addr);
        return PROTOCOL_ERROR_ASDU_INVALID_ADDRESS;
    }
    
    if (!is_scaled_value_valid(value->value)) {
        LOG_ERROR(LOG_MODULE_NAME, "标度化值无效: %d", value->value);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    if (!is_qds_valid(*(uint8_t*)&value->qds)) {
        LOG_ERROR(LOG_MODULE_NAME, "品质描述词无效: 0x%02X", *(u8*)&value->qds);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    LOG_INFO(LOG_MODULE_NAME, "标度化值转换成功: 地址=0x%06X, 值=%d, QDS=0x%02X", 
             value->addr, value->value, *(u8*)&value->qds);
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 验证标度化值
 * @details 验证标度化值结构的完整性和有效性。
 *          检查地址、数值和品质描述词的有效性。
 * 
 * @param value 标度化值结构，不能为NULL
 * @return 验证结果
 *         - 1: 标度化值有效
 *         - 0: 标度化值无效
 * 
 * @note 验证地址、数值和品质描述词的有效性
 * @warning 输入指针不能为NULL
 * 
 * @see is_info_address_valid
 * @see is_scaled_value_valid
 * @see is_qds_valid
 * @see scaled_value_t
 */
int validate_scaled_value(const scaled_value_t* value) {
    if (value == NULL) {
        return 0;
    }
    
    return (is_info_address_valid(value->addr) && 
            is_scaled_value_valid(value->value) && 
            is_qds_valid(*(uint8_t*)&value->qds));
}

/* ==================== 短浮点值处理函数实现 ==================== */

/**
 * @brief 短浮点值转换为字节数组
 * @details 将短浮点值结构转换为104协议规定的字节数组格式。
 *          按照协议规范进行数据序列化。
 * 
 * @param value 短浮点值结构，不能为NULL
 * @param buffer 输出缓冲区，不能为NULL
 * @param buffer_size 缓冲区大小
 * @param actual_length 实际写入长度输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 缓冲区太小
 *         - PROTOCOL_ERROR_INVALID_ADDRESS: 地址无效
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 按照104协议规范进行数据序列化
 * @warning 缓冲区大小必须足够容纳转换后的数据
 * 
 * @see bytes_to_short_float_value
 * @see validate_short_float_value
 * @see buffer_write_u24
 * @see buffer_write_f32
 * @see buffer_write_u8
 */
protocol_error_t short_float_value_to_bytes(const short_float_value_t* value,
                                           u8* buffer, u32 buffer_size, u32* actual_length) {
    LOG_DEBUG(LOG_MODULE_NAME, "转换短浮点值到字节数组: value=%p, buffer=%p, buffer_size=%u", 
              value, buffer, buffer_size);
    
    if (value == NULL || buffer == NULL || actual_length == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 验证短浮点值 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证短浮点值数据: 地址=0x%06X, 值=%f, QDS=0x%02X", 
              value->addr, value->value, *(u8*)&value->qds);
    
    if (!is_info_address_valid(value->addr)) {
        LOG_ERROR(LOG_MODULE_NAME, "信息对象地址无效: 0x%06X", value->addr);
        return PROTOCOL_ERROR_ASDU_INVALID_ADDRESS;
    }
    
    if (!is_short_float_valid(value->value)) {
        LOG_ERROR(LOG_MODULE_NAME, "短浮点值无效: %f", value->value);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    if (!is_qds_valid(*(uint8_t*)&value->qds)) {
        LOG_ERROR(LOG_MODULE_NAME, "品质描述词无效: 0x%02X", *(u8*)&value->qds);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "短浮点值数据验证通过");
    
    /* 检查缓冲区大小 */
    if (buffer_size < 8) { /* 地址(3字节) + 值(4字节) + QDS(1字节) */
        LOG_ERROR(LOG_MODULE_NAME, "缓冲区太小: %u < 8", buffer_size);
        return PROTOCOL_ERROR_BUFFER_TOO_SMALL;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "缓冲区大小检查通过: %u >= 8", buffer_size);
    
    /* 写入信息对象地址 */
    LOG_DEBUG(LOG_MODULE_NAME, "写入信息对象地址: 0x%06X 到缓冲区[0-2]", value->addr);
    buffer_write_u32(buffer, 0, value->addr, 0);
    
    /* 写入短浮点值 */
    LOG_DEBUG(LOG_MODULE_NAME, "写入短浮点值: %f 到缓冲区[3-6]", value->value);
    buffer_write_f32(&buffer[3], 0, value->value, 0);
    
    /* 写入品质描述词 */
    LOG_DEBUG(LOG_MODULE_NAME, "写入品质描述词: 0x%02X 到缓冲区[7]", *(u8*)&value->qds);
    buffer[7] = *(u8*)&value->qds;
    
    *actual_length = 8;
    LOG_INFO(LOG_MODULE_NAME, "短浮点值转换成功: 地址=0x%06X, 值=%f, QDS=0x%02X, 长度=%u", 
             value->addr, value->value, *(u8*)&value->qds, *actual_length);
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 字节数组转换为短浮点值
 * @details 将104协议规定的字节数组格式转换为短浮点值结构。
 *          按照协议规范进行数据反序列化。
 * 
 * @param data 字节数组，不能为NULL
 * @param length 数据长度
 * @param value 短浮点值结构输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 数据长度不足
 *         - PROTOCOL_ERROR_INVALID_ADDRESS: 地址无效
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 按照104协议规范进行数据反序列化
 * @warning 数据长度必须足够容纳短浮点值
 * 
 * @see short_float_value_to_bytes
 * @see validate_short_float_value
 * @see buffer_read_u24
 * @see buffer_read_f32
 * @see buffer_read_u8
 */
protocol_error_t bytes_to_short_float_value(const u8* data, u32 length,
                                           short_float_value_t* value) {
    LOG_DEBUG(LOG_MODULE_NAME, "从字节数组转换短浮点值: data=%p, length=%u, value=%p", 
              data, length, value);
    
    if (data == NULL || value == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 检查数据长度 */
    if (length < 8) { /* 地址(3字节) + 值(4字节) + QDS(1字节) */
        LOG_ERROR(LOG_MODULE_NAME, "数据长度太小: %u < 8", length);
        return PROTOCOL_ERROR_BUFFER_TOO_SMALL;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "数据长度检查通过: %u >= 8", length);
    
    /* 读取信息对象地址 */
    LOG_DEBUG(LOG_MODULE_NAME, "读取信息对象地址从缓冲区[0-2]");
    buffer_read_u32(data, 0, (u32*)&value->addr, 0);
    
    /* 读取短浮点值 */
    LOG_DEBUG(LOG_MODULE_NAME, "读取短浮点值从缓冲区[3-6]");
    buffer_read_f32(&data[3], 0, &value->value, 0);
    
    /* 读取品质描述词 */
    LOG_DEBUG(LOG_MODULE_NAME, "读取品质描述词从缓冲区[7]");
    memcpy(&value->qds, &data[7], sizeof(qds_t));
    
    LOG_DEBUG(LOG_MODULE_NAME, "读取完成: 地址=0x%06X, 值=%f, QDS=0x%02X", 
              value->addr, value->value, *(u8*)&value->qds);
    
    /* 验证转换后的数据 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证转换后的数据");
    if (!is_info_address_valid(value->addr)) {
        LOG_ERROR(LOG_MODULE_NAME, "信息对象地址无效: 0x%06X", value->addr);
        return PROTOCOL_ERROR_ASDU_INVALID_ADDRESS;
    }
    
    if (!is_short_float_valid(value->value)) {
        LOG_ERROR(LOG_MODULE_NAME, "短浮点值无效: %f", value->value);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    if (!is_qds_valid(*(uint8_t*)&value->qds)) {
        LOG_ERROR(LOG_MODULE_NAME, "品质描述词无效: 0x%02X", *(u8*)&value->qds);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    LOG_INFO(LOG_MODULE_NAME, "短浮点值转换成功: 地址=0x%06X, 值=%f, QDS=0x%02X", 
             value->addr, value->value, *(u8*)&value->qds);
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 验证短浮点值
 * @details 验证短浮点值结构的完整性和有效性。
 *          检查地址、数值和品质描述词的有效性。
 * 
 * @param value 短浮点值结构，不能为NULL
 * @return 验证结果
 *         - 1: 短浮点值有效
 *         - 0: 短浮点值无效
 * 
 * @note 验证地址、数值和品质描述词的有效性
 * @warning 输入指针不能为NULL
 * 
 * @see is_info_address_valid
 * @see is_short_float_valid
 * @see is_qds_valid
 * @see short_float_value_t
 */
int validate_short_float_value(const short_float_value_t* value) {
    if (value == NULL) {
        return 0;
    }
    
    return (is_info_address_valid(value->addr) && 
            is_short_float_valid(value->value) && 
            is_qds_valid(*(uint8_t*)&value->qds));
}

/* ==================== 带时标的归一化值处理函数实现 ==================== */

/**
 * @brief 带时标的归一化值转换为字节数组
 * @details 将带时标的归一化值结构转换为104协议规定的字节数组格式。
 *          按照协议规范进行数据序列化，包含时间戳信息。
 * 
 * @param value 带时标的归一化值结构，不能为NULL
 * @param buffer 输出缓冲区，不能为NULL
 * @param buffer_size 缓冲区大小
 * @param actual_length 实际写入长度输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 缓冲区太小
 *         - PROTOCOL_ERROR_INVALID_ADDRESS: 地址无效
 *         - PROTOCOL_ERROR_INVALID_TIMESTAMP: 时间戳无效
 * 
 * @note 按照104协议规范进行数据序列化，包含时间戳
 * @warning 缓冲区大小必须足够容纳转换后的数据
 * 
 * @see bytes_to_normalized_value_with_time
 * @see validate_normalized_value_with_time
 * @see buffer_write_u24
 * @see buffer_write_s16
 * @see buffer_write_u8
 * @see cp56time2a_to_bytes
 */
protocol_error_t normalized_value_with_time_to_bytes(const normalized_value_with_time_t* value,
                                                   u8* buffer, u32 buffer_size, u32* actual_length) {
    LOG_DEBUG(LOG_MODULE_NAME, "转换带时标的归一化值到字节数组: value=%p, buffer=%p, buffer_size=%u", 
              value, buffer, buffer_size);
    
    if (value == NULL || buffer == NULL || actual_length == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 验证带时标的归一化值 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证带时标的归一化值数据: 地址=0x%06X, 值=%d, QDS=0x%02X", 
              value->addr, value->value, *(u8*)&value->qds);
    
    if (!is_info_address_valid(value->addr)) {
        LOG_ERROR(LOG_MODULE_NAME, "信息对象地址无效: 0x%06X", value->addr);
        return PROTOCOL_ERROR_ASDU_INVALID_ADDRESS;
    }
    
    if (!is_normalized_value_valid(value->value)) {
        LOG_ERROR(LOG_MODULE_NAME, "归一化值无效: %d", value->value);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    if (!is_qds_valid(*(uint8_t*)&value->qds)) {
        LOG_ERROR(LOG_MODULE_NAME, "品质描述词无效: 0x%02X", *(u8*)&value->qds);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    if (!is_cp56time2a_valid(&value->time)) {
        LOG_ERROR(LOG_MODULE_NAME, "时间戳无效");
        return PROTOCOL_ERROR_DATA_INVALID_TIMESTAMP;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "带时标的归一化值数据验证通过");
    
    /* 检查缓冲区大小 */
    if (buffer_size < 13) { /* 地址(3字节) + 值(2字节) + QDS(1字节) + 时间戳(7字节) */
        LOG_ERROR(LOG_MODULE_NAME, "缓冲区太小: %u < 13", buffer_size);
        return PROTOCOL_ERROR_BUFFER_TOO_SMALL;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "缓冲区大小检查通过: %u >= 13", buffer_size);
    
    /* 写入信息对象地址 */
    LOG_DEBUG(LOG_MODULE_NAME, "写入信息对象地址: 0x%06X 到缓冲区[0-2]", value->addr);
    buffer_write_u32(buffer, 0, value->addr, 0);
    
    /* 写入归一化值 */
    LOG_DEBUG(LOG_MODULE_NAME, "写入归一化值: %d 到缓冲区[3-4]", value->value);
    buffer_write_u16(&buffer[3], 0, (u16)value->value, 0);
    
    /* 写入品质描述词 */
    LOG_DEBUG(LOG_MODULE_NAME, "写入品质描述词: 0x%02X 到缓冲区[5]", *(u8*)&value->qds);
    buffer[5] = *(u8*)&value->qds;
    
    /* 写入时间戳 */
    LOG_DEBUG(LOG_MODULE_NAME, "写入时间戳到缓冲区[6-12]");
    memcpy(&buffer[6], &value->time, 7);
    protocol_error_t result = PROTOCOL_SUCCESS;
    if (result != PROTOCOL_SUCCESS) {
        LOG_ERROR(LOG_MODULE_NAME, "时间戳写入失败");
        return result;
    }
    
    *actual_length = 13;
    LOG_INFO(LOG_MODULE_NAME, "带时标的归一化值转换成功: 地址=0x%06X, 值=%d, QDS=0x%02X, 长度=%u", 
             value->addr, value->value, *(u8*)&value->qds, *actual_length);
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 字节数组转换为带时标的归一化值
 * @details 将104协议规定的字节数组格式转换为带时标的归一化值结构。
 *          按照协议规范进行数据反序列化，包含时间戳信息。
 * 
 * @param data 字节数组，不能为NULL
 * @param length 数据长度
 * @param value 带时标的归一化值结构输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 数据长度不足
 *         - PROTOCOL_ERROR_INVALID_ADDRESS: 地址无效
 *         - PROTOCOL_ERROR_INVALID_TIMESTAMP: 时间戳无效
 * 
 * @note 按照104协议规范进行数据反序列化，包含时间戳
 * @warning 数据长度必须足够容纳带时标的归一化值
 * 
 * @see normalized_value_with_time_to_bytes
 * @see validate_normalized_value_with_time
 * @see buffer_read_u24
 * @see buffer_read_s16
 * @see buffer_read_u8
 * @see bytes_to_cp56time2a
 */
protocol_error_t bytes_to_normalized_value_with_time(const u8* data, u32 length,
                                                    normalized_value_with_time_t* value) {
    LOG_DEBUG(LOG_MODULE_NAME, "从字节数组转换带时标的归一化值: data=%p, length=%u, value=%p", 
              data, length, value);
    
    if (data == NULL || value == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 检查数据长度 */
    if (length < 13) { /* 地址(3字节) + 值(2字节) + QDS(1字节) + 时间戳(7字节) */
        LOG_ERROR(LOG_MODULE_NAME, "数据长度太小: %u < 13", length);
        return PROTOCOL_ERROR_BUFFER_TOO_SMALL;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "数据长度检查通过: %u >= 13", length);
    
    /* 读取信息对象地址 */
    LOG_DEBUG(LOG_MODULE_NAME, "读取信息对象地址从缓冲区[0-2]");
    buffer_read_u32(data, 0, (u32*)&value->addr, 0);
    
    /* 读取归一化值 */
    LOG_DEBUG(LOG_MODULE_NAME, "读取归一化值从缓冲区[3-4]");
    buffer_read_u16(&data[3], 0, (u16*)&value->value, 0);
    
    /* 读取品质描述词 */
    LOG_DEBUG(LOG_MODULE_NAME, "读取品质描述词从缓冲区[5]");
    value->qds = *(qds_t*)&data[5];
    
    /* 读取时间戳 */
    LOG_DEBUG(LOG_MODULE_NAME, "读取时间戳从缓冲区[6-12]");
    memcpy(&value->time, &data[6], 7);
    protocol_error_t result = PROTOCOL_SUCCESS;
    if (result != PROTOCOL_SUCCESS) {
        LOG_ERROR(LOG_MODULE_NAME, "时间戳读取失败");
        return result;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "读取完成: 地址=0x%06X, 值=%d, QDS=0x%02X", 
              value->addr, value->value, *(u8*)&value->qds);
    
    /* 验证转换后的数据 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证转换后的数据");
    if (!is_info_address_valid(value->addr)) {
        LOG_ERROR(LOG_MODULE_NAME, "信息对象地址无效: 0x%06X", value->addr);
        return PROTOCOL_ERROR_ASDU_INVALID_ADDRESS;
    }
    
    if (!is_normalized_value_valid(value->value)) {
        LOG_ERROR(LOG_MODULE_NAME, "归一化值无效: %d", value->value);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    if (!is_qds_valid(*(uint8_t*)&value->qds)) {
        LOG_ERROR(LOG_MODULE_NAME, "品质描述词无效: 0x%02X", *(u8*)&value->qds);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    if (!is_cp56time2a_valid(&value->time)) {
        LOG_ERROR(LOG_MODULE_NAME, "时间戳无效");
        return PROTOCOL_ERROR_DATA_INVALID_TIMESTAMP;
    }
    
    LOG_INFO(LOG_MODULE_NAME, "带时标的归一化值转换成功: 地址=0x%06X, 值=%d, QDS=0x%02X", 
             value->addr, value->value, *(u8*)&value->qds);
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 验证带时标的归一化值
 * @details 验证带时标的归一化值结构的完整性和有效性。
 *          检查地址、数值、品质描述词和时间戳的有效性。
 * 
 * @param value 带时标的归一化值结构，不能为NULL
 * @return 验证结果
 *         - 1: 带时标的归一化值有效
 *         - 0: 带时标的归一化值无效
 * 
 * @note 验证地址、数值、品质描述词和时间戳的有效性
 * @warning 输入指针不能为NULL
 * 
 * @see is_info_address_valid
 * @see is_normalized_value_valid
 * @see is_qds_valid
 * @see is_cp56time2a_valid
 * @see normalized_value_with_time_t
 */
int validate_normalized_value_with_time(const normalized_value_with_time_t* value) {
    if (value == NULL) {
        return 0;
    }
    
    return (is_info_address_valid(value->addr) && 
            is_normalized_value_valid(value->value) && 
            is_qds_valid(*(uint8_t*)&value->qds) && 
            is_cp56time2a_valid(&value->time));
}

/* ==================== 累计量处理函数实现 ==================== */

/**
 * @brief 累计量转换为字节数组
 * @details 将累计量结构转换为104协议规定的字节数组格式。
 *          按照协议规范进行数据序列化。
 * 
 * @param value 累计量结构，不能为NULL
 * @param buffer 输出缓冲区，不能为NULL
 * @param buffer_size 缓冲区大小
 * @param actual_length 实际写入长度输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 缓冲区太小
 *         - PROTOCOL_ERROR_INVALID_ADDRESS: 地址无效
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 按照104协议规范进行数据序列化
 * @warning 缓冲区大小必须足够容纳转换后的数据
 * 
 * @see bytes_to_accumulated_value
 * @see validate_accumulated_value
 * @see buffer_write_u24
 * @see buffer_write_f32
 * @see buffer_write_u8
 */
protocol_error_t accumulated_value_to_bytes(const measurement_info_t* value,
                                          u8* buffer, u32 buffer_size, u32* actual_length) {
    LOG_DEBUG(LOG_MODULE_NAME, "转换累计量到字节数组: value=%p, buffer=%p, buffer_size=%u", 
              value, buffer, buffer_size);
    
    if (value == NULL || buffer == NULL || actual_length == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 验证累计量 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证累计量数据");
    if (!is_info_address_valid(value->info_addr)) {
        LOG_ERROR(LOG_MODULE_NAME, "信息对象地址无效: %u", value->info_addr);
        return PROTOCOL_ERROR_ASDU_INVALID_ADDRESS;
    }
    
    if (!is_normalized_value_valid((s16)value->value)) {
        LOG_ERROR(LOG_MODULE_NAME, "累计量值无效: %f", value->value);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    if (!is_qds_valid(*(uint8_t*)&value->qds)) {
        LOG_ERROR(LOG_MODULE_NAME, "品质描述词无效: 0x%02X", *(u8*)&value->qds);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    /* 检查缓冲区大小 */
    if (buffer_size < 8) { /* 地址(3字节) + 值(4字节) + QDS(1字节) */
        LOG_ERROR(LOG_MODULE_NAME, "缓冲区太小: %u < 8", buffer_size);
        return PROTOCOL_ERROR_BUFFER_TOO_SMALL;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "开始写入累计量数据到缓冲区");
    
    /* 写入信息对象地址 */
    LOG_DEBUG(LOG_MODULE_NAME, "写入信息对象地址: %u", value->info_addr);
    buffer_write_u32(buffer, 0, value->info_addr, 0);
    
    /* 写入累计量值 */
    LOG_DEBUG(LOG_MODULE_NAME, "写入累计量值: %f", value->value);
    buffer_write_f32(&buffer[3], 0, value->value, 0);
    
    /* 写入品质描述词 */
    LOG_DEBUG(LOG_MODULE_NAME, "写入品质描述词: 0x%02X", *(u8*)&value->qds);
    buffer[7] = *(u8*)&value->qds;
    
    *actual_length = 8;
    LOG_INFO(LOG_MODULE_NAME, "累计量转换成功: 地址=%u, 值=%f, QDS=0x%02X, 长度=%u", 
             value->info_addr, value->value, *(u8*)&value->qds, *actual_length);
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 字节数组转换为累计量
 * @details 将104协议规定的字节数组格式转换为累计量结构。
 *          按照协议规范进行数据反序列化。
 * 
 * @param data 字节数组，不能为NULL
 * @param length 数据长度
 * @param value 累计量结构输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 转换成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 数据长度不足
 *         - PROTOCOL_ERROR_INVALID_ADDRESS: 地址无效
 *         - PROTOCOL_ERROR_DATA_INVALID_VALUE: 数据值无效
 * 
 * @note 按照104协议规范进行数据反序列化
 * @warning 数据长度必须足够容纳累计量
 * 
 * @see accumulated_value_to_bytes
 * @see validate_accumulated_value
 * @see buffer_read_u24
 * @see buffer_read_f32
 * @see buffer_read_u8
 */
protocol_error_t bytes_to_accumulated_value(const u8* data, u32 length,
                                            measurement_info_t* value) {
    LOG_DEBUG(LOG_MODULE_NAME, "从字节数组转换累计量: data=%p, length=%u, value=%p", 
              data, length, value);
    
    if (data == NULL || value == NULL) {
        LOG_ERROR(LOG_MODULE_NAME, "空指针参数错误");
        return PROTOCOL_ERROR_NULL_POINTER;
    }
    
    /* 检查数据长度 */
    if (length < 8) { /* 地址(3字节) + 值(4字节) + QDS(1字节) */
        LOG_ERROR(LOG_MODULE_NAME, "数据长度太小: %u < 8", length);
        return PROTOCOL_ERROR_BUFFER_TOO_SMALL;
    }
    
    LOG_DEBUG(LOG_MODULE_NAME, "数据长度检查通过: %u >= 8", length);
    
    /* 读取信息对象地址 */
    LOG_DEBUG(LOG_MODULE_NAME, "读取信息对象地址从缓冲区[0-2]");
    buffer_read_u32(data, 0, (u32*)&value->info_addr, 0);
    
    /* 读取累计量值 */
    LOG_DEBUG(LOG_MODULE_NAME, "读取累计量值从缓冲区[3-6]");
    buffer_read_u32(&data[3], 0, &value->value, 0);
    
    /* 读取品质描述词 */
    LOG_DEBUG(LOG_MODULE_NAME, "读取品质描述词从缓冲区[7]");
    memcpy(&value->qds, &data[7], sizeof(qds_t));
    
    LOG_DEBUG(LOG_MODULE_NAME, "读取完成: 地址=%u, 值=%f, QDS=0x%02X", 
              value->info_addr, value->value, *(u8*)&value->qds);
    
    /* 验证转换后的数据 */
    LOG_DEBUG(LOG_MODULE_NAME, "验证转换后的数据");
    if (!is_info_address_valid(value->info_addr)) {
        LOG_ERROR(LOG_MODULE_NAME, "信息对象地址无效: %u", value->info_addr);
        return PROTOCOL_ERROR_ASDU_INVALID_ADDRESS;
    }
    
    if (!is_normalized_value_valid((s16)value->value)) {
        LOG_ERROR(LOG_MODULE_NAME, "累计量值无效: %f", value->value);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    if (!is_qds_valid(*(uint8_t*)&value->qds)) {
        LOG_ERROR(LOG_MODULE_NAME, "品质描述词无效: 0x%02X", *(u8*)&value->qds);
        return PROTOCOL_ERROR_DATA_INVALID_VALUE;
    }
    
    LOG_INFO(LOG_MODULE_NAME, "累计量转换成功: 地址=%u, 值=%f, QDS=0x%02X", 
             value->info_addr, value->value, *(u8*)&value->qds);
    return PROTOCOL_SUCCESS;
}

/**
 * @brief 验证累计量
 * @details 验证累计量结构的完整性和有效性。
 *          检查地址、数值和品质描述词的有效性。
 * 
 * @param value 累计量结构，不能为NULL
 * @return 验证结果
 *         - 1: 累计量有效
 *         - 0: 累计量无效
 * 
 * @note 验证地址、数值和品质描述词的有效性
 * @warning 输入指针不能为NULL
 * 
 * @see is_info_address_valid
 * @see is_energy_value_valid
 * @see is_qds_valid
 * @see accumulated_value_t
 */
int validate_accumulated_value(const measurement_info_t* value) {
    if (value == NULL) {
        return 0;
    }
    
    return (is_info_address_valid(value->info_addr) && 
            is_normalized_value_valid((s16)value->value) && 
            is_qds_valid(*(uint8_t*)&value->qds));
}

/* ==================== 辅助函数实现 ==================== */

/**
 * @brief 获取归一化值大小
 * @details 获取归一化值结构在字节数组中的大小。
 *          用于缓冲区大小计算。
 * 
 * @return 归一化值大小（字节）
 * 
 * @note 归一化值大小：6字节（地址3字节 + 值2字节 + QDS1字节）
 * @warning 此函数是线程安全的
 * 
 * @see get_scaled_value_size
 * @see get_short_float_value_size
 * @see normalized_value_t
 */
u32 get_normalized_value_size(void) {
    return 6; /* 地址(3字节) + 值(2字节) + QDS(1字节) */
}

/**
 * @brief 获取标度化值大小
 * @details 获取标度化值结构在字节数组中的大小。
 *          用于缓冲区大小计算。
 * 
 * @return 标度化值大小（字节）
 * 
 * @note 标度化值大小：6字节（地址3字节 + 值2字节 + QDS1字节）
 * @warning 此函数是线程安全的
 * 
 * @see get_normalized_value_size
 * @see get_short_float_value_size
 * @see scaled_value_t
 */
u32 get_scaled_value_size(void) {
    return 6; /* 地址(3字节) + 值(2字节) + QDS(1字节) */
}

/**
 * @brief 获取短浮点值大小
 * @details 获取短浮点值结构在字节数组中的大小。
 *          用于缓冲区大小计算。
 * 
 * @return 短浮点值大小（字节）
 * 
 * @note 短浮点值大小：8字节（地址3字节 + 值4字节 + QDS1字节）
 * @warning 此函数是线程安全的
 * 
 * @see get_normalized_value_size
 * @see get_scaled_value_size
 * @see short_float_value_t
 */
u32 get_short_float_value_size(void) {
    return 8; /* 地址(3字节) + 值(4字节) + QDS(1字节) */
}

/**
 * @brief 获取带时标的归一化值大小
 * @details 获取带时标的归一化值结构在字节数组中的大小。
 *          用于缓冲区大小计算。
 * 
 * @return 带时标的归一化值大小（字节）
 * 
 * @note 带时标的归一化值大小：13字节（地址3字节 + 值2字节 + QDS1字节 + 时间戳7字节）
 * @warning 此函数是线程安全的
 * 
 * @see get_normalized_value_size
 * @see get_scaled_value_with_time_size
 * @see normalized_value_with_time_t
 */
u32 get_normalized_value_with_time_size(void) {
    return 13; /* 地址(3字节) + 值(2字节) + QDS(1字节) + 时间戳(7字节) */
}

/**
 * @brief 获取累计量大小
 * @details 获取累计量结构在字节数组中的大小。
 *          用于缓冲区大小计算。
 * 
 * @return 累计量大小（字节）
 * 
 * @note 累计量大小：8字节（地址3字节 + 值4字节 + QDS1字节）
 * @warning 此函数是线程安全的
 * 
 * @see get_short_float_value_size
 * @see get_normalized_value_size
 * @see accumulated_value_t
 */
u32 get_accumulated_value_size(void) {
    return 8; /* 地址(3字节) + 值(4字节) + QDS(1字节) */
}
